using System;
using System.Collections.Generic;
using Token = TBit.Compile.ASMCompile.Token;
using TBit.Compile;

namespace TBit.Instrcutions {
    public static class Mov {
        public static int Compile(List<Token> tokens,VM vm,int i) {
            return ASMCompile.StructureInstruction_OPCODE_DVR_R(Opcode.MOV,tokens,vm,i);
        }

        public static Instruction Create(RegisterIndex a,RegisterIndex b) {
            Instruction inst = new Instruction();
            inst.opcode = Opcode.MOV;
            inst.args.Add(new InstructionArgData(a));
            inst.args.Add(new InstructionArgData(b));
            return inst;
        }

        public static Instruction Create(string a,RegisterIndex b) {
            Instruction inst = new Instruction();
            inst.opcode = Opcode.MOV;
            inst.args.Add(new InstructionArgData(a));
            inst.args.Add(new InstructionArgData(b));
            return inst;
        }

        public static Instruction Create(Data a,RegisterIndex b) {
            Instruction inst = new Instruction();
            inst.opcode = Opcode.MOV;
            inst.args.Add(new InstructionArgData(a));
            inst.args.Add(new InstructionArgData(b));
            return inst;
        }

        public static Data GetDVRData(VM vm,ref InstructionArgData data){
            switch(data.type)
            {
                case InstructionArgDataType.Data : return data.data;
                case InstructionArgDataType.Register : return vm.registers[(int)data.register];
                case InstructionArgDataType.Variable : return vm.GetData(data.variable);
            }
            return null;
        }

        public static int Run(VM vm,Instruction inst){
            InstructionArgData arg1 = inst.args[0];
            InstructionArgData arg2 = inst.args[1];
            Data data = GetDVRData(vm,ref arg1);
            RegisterIndex register = arg2.register;
            vm.registers[(int)register] = data;
            return 1;
        }
    }
}